﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

namespace Utility.NodeGraphs
{
	public class TreeNode : Node
	{
		public bool isRoot = false;

		public virtual NodePort ParentPort => nodePorts[0];
		public virtual IEnumerable<NodePort> ChildPorts => nodePorts.Skip (1);

		public override PortOnMaxConnectionBehaviours GetPortOnMaxConnectionBehaviour (int index)
		{
			return PortOnMaxConnectionBehaviours.OverrideLastConnection;
		}

		public virtual int ChildPortCount => nodePorts.Count - 1;

		public virtual int ChildPortCount_Min => 0;
		public virtual int ChildPortCount_Max => -1;

		public bool ReachMaxChildPortCount => ChildPortCount_Max >= 0 && ChildPortCount >= ChildPortCount_Max;
		public bool ReachMinChildPortCount => ChildPortCount <= ChildPortCount_Min;

		public IEnumerable<TreeNode> ChildNodes => from childPort in ChildPorts
												   from output in childPort.outputs
												   select output.targetNode as TreeNode;

		public override void OnAwake ()
		{
			//parent
			if (nodePorts.Count == 0)
			{
				AddNewPort (1, 0, Vector2.left * 50);
			}
		}

		public override bool CanAddPort () => !ReachMaxChildPortCount;
		public override bool CanRemovePort (int index) => nodePorts[index] != ParentPort && !ReachMinChildPortCount;

		public override bool PortCanConnectFrom (int index, NodePort sourcePort)
		{
			if (!base.PortCanConnectFrom (index, sourcePort))
			{
				return false;
			}
			//only allow connect treenode
			if (sourcePort.Node as TreeNode == null)
			{
				return false;
			}
			return true;
		}

		public override bool PortCanConnectTo (int index, NodePort targetPort)
		{
			if (!base.PortCanConnectTo (index, targetPort))
			{
				return false;
			}
			//only allow connect treenode
			if (targetPort.Node as TreeNode == null)
			{
				return false;
			}
			return true;
		}

		public NodePort AddChildPort ()
		{
			return AddNewPort (0, 1, Vector2.right * 50);
		}
	}
}